<?php

namespace App\Library;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Ip2Region;

class ClientIp
{
    /**
     * @param string $ip
     * @return array
     */
    public static function getLocation(string $ip): array
    {
        empty($ip) && $ip = getClientIp();
        $method = config('custom.ipMethod');
        return $method === 'whois' ? self::whoisLocation($ip) : self::getIp2Region($ip);
    }

    /**
     * @param string $ip
     * @return array
     */
    private static function getIp2Region(string $ip): array
    {
        try {
            $info = (new Ip2Region())->btreeSearch($ip);
            [$country, $area, $province, $city] = explode("|", $info["region"]);
            return [
                "country" => $country,
                "region" => $info["region"],
                "province" => $province,
                "province_code" => '',
                "city" => $city,
                "city_code" => '',
                "area" => $area,
                "area_code" => '',
            ];
        }catch (\Exception $e) {
            report($e);
        }
        return [];
    }

    /**
     * @param string $ip
     * @return array
     */
    private static function whoisLocation(string $ip): array
    {
        try {
            //https://ipwhois.io/
            $resp = (new Client(['timeout' => 5.0, 'verify' => false]))->get('https://whois.pconline.com.cn/ipJson.jsp', [
                'query' => [
                    'json' => true,
                    'ip' => $ip,
                ],
                'headers' => [
                    'Content-Type' => 'application/json;charset=UTF-8',
                ]
            ]);
            $data = json_decode($resp->getBody()->getContents(), true);
            return !empty($data) ? [
                "country" => '',
                "region" => $data["addr"],
                "province" => $data["pro"],
                "province_code" => $data["proCode"],
                "city" => $data["city"],
                "city_code" => $data["cityCode"],
                "area" => $data["region"],
                "area_code" => $data["regionCode"],
            ] : [];
        }catch (GuzzleException $e) {
            report($e);
        }
        return [];
    }
}
